/*************************************************************************************
* Copyright (c) 2021 xffish
* c_plus_plus_primer_exercise is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*************************************************************************************/

#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;


class HasPtr
{
public:
	HasPtr(int, string* );
	// HasPtr(const HasPtr&);
	HasPtr& operator=(const HasPtr&);
	~HasPtr();
	void show();
	
private:
	int a;
	string* b;	
};

HasPtr::HasPtr(int tmpa, string*  tmpb):a(tmpa),b(new string(*tmpb))
{
	cout << "构造函数" << endl;
}

// HasPtr::HasPtr(const HasPtr& tmpHp):a(tmpHp.a), b(new string(*tmpHp.b))
// {
// 	cout << "拷贝构造函数" << endl;
// }

HasPtr& HasPtr::operator=(const HasPtr& tmpHp)
{
	/************************************
	//这样是错误做法，如果是自己给自己赋值将导致从已释放的内存中拷贝数据
	delete b;
	b = new string(*tmpHp.b);
	************************************/

	//**************************************
	//应该这样做
	auto temp = new string(*tmpHp.b);
	delete b;
	b = temp;
	//**************************************/

	a = tmpHp.a;

	return *this;
}

HasPtr::~HasPtr()
{
	delete b;
}

void HasPtr::show()
{
	cout << "a=" << a << ",&b=" << b << ",b=" << *b << endl;
}

int main()
{
	auto strp1 = new string("apple");
	auto strp2 = new string("banana");
	
	HasPtr hp1(0, strp1);
	hp1.show();
	HasPtr hp2(hp1); //调用了拷贝构造函数，但是应该算直接初始化，见书P441举例
	hp2.show();
	HasPtr hp3 = hp2;
	hp3.show();
	hp1 = hp3;
	hp1.show();

	cout << "===========" << endl;
	hp1 = hp1;
	hp1.show();
	
	delete strp1;
	delete strp2;
	return 0;
}